﻿using MesCommunicationTools.Helper;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TIBCO.Rendezvous;
using xxw.Config;

namespace MesCommunicationTools
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// 配置文件数据模型
        /// </summary>
        private ConfigModel Config => App.Config;
        /// <summary>
        /// 将XLSX表格解析后存入List集合中
        /// </summary>
        public List<GYSHelperClass> GYSLHC = new List<GYSHelperClass>();
        public List<HelperClass> LHC = new List<HelperClass>();
        public Transport transport = null;


        public List<string> DeamonList = new List<string>();
        public ObservableCollection<string> Logs { get; set; } = new ObservableCollection<string>();

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        /// <summary>
        /// Excel表格中有新数据标识
        /// </summary>
        public bool ExcelHave = false;
        /// <summary>
        /// Csv路径
        /// </summary>
        public string str = System.Environment.CurrentDirectory;

        public FileStream fs = null;

        /// <summary>
        /// Csv实时监听标识
        /// </summary>
        public bool CsvListeningBS = true;
        /// <summary>
        /// Tibco实时发送小时监听标识
        /// </summary>
        public bool TibcoListeningBS = true;

        public string ttx;
        public string Ttx
        {
            get { return ttx; }
            set
            {
                ttx = value;
                //OnPropertyChanged(nameof(Ttx));
            }
        }

        public SolidColorBrush ttxcl;
        public SolidColorBrush Ttxcl
        {
            get { return ttxcl; }
            set
            {
                ttxcl = value;
                OnPropertyChanged(nameof(Ttxcl));
            }
        }

        public string TibcoStatus = "";

        public string TibcoStatusColor = "";
        public MainWindow()
        {
            //读取配置文件并存到数据模型中
            ConfigHelper.Init("config.json");
            App.Config = ConfigHelper.GetConfig<ConfigModel>();
            //读取配置文件并存到数据模型中
            DeamonList.Add(Config.MesCommunicationsConfiguration.Daemon1);
            DeamonList.Add(Config.MesCommunicationsConfiguration.Daemon2);
            DeamonList.Add(Config.MesCommunicationsConfiguration.Daemon3);
            DeamonList.Add(Config.MesCommunicationsConfiguration.Daemon4);
            DeamonList.Add(Config.MesCommunicationsConfiguration.Daemon5);
            DeamonList.Add(Config.MesCommunicationsConfiguration.Daemon6);

            InitializeComponent();

            DataContext = this;
            OnPropertyChanged(nameof(Logs));

            try
            {
                try
                {
                    FileInfo fi = new FileInfo(Config.LocalFileUrl);
                    dtf = fi.LastWriteTime;
                }
                catch (Exception ex)
                {
                    AddMcLogs(ex.Message);
                }

                try
                {
                    FileInfo fiTwice = new FileInfo(Config.LocalFileUrlTwice);
                    dtfTwice = fiTwice.LastWriteTime;
                }
                catch (Exception ex)
                {
                    AddMcLogs(ex.Message);
                }
                ////Tibco服务--实时监听并重连
                TibcoInitReConnect();
                ////Csv文件读取--实时监听
                CsvListening();
                ////Csv数据发送给Mes--实时监听
                CsvDataSendListening();
            }
            catch (Exception ex)
            {
                AddMcLogs(ex.Message);
            }

        }

        
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            //禁用关闭按钮
            e.Cancel = true;
        }
        //保存Csv表格上次修改时间
        public DateTime dtf = DateTime.Now;
        //保存Csv表格上次修改时间
        public DateTime dtfTwice = DateTime.Now;
        public bool la = false;

        /// <summary>
        /// 实时监听Tibco服务状态，若消息发送失败，则自动重新连接
        /// </summary>
        public void TibcoInitReConnect()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    if (transport == null)
                    {
                        upui(Ticst, "Tibco服务正在重新连接......", Brushes.Orange);
                        TibcoInit();
                    }
                    Task.Delay(5000).Wait();
                }
            });
        }

        public bool DeleteBS = false;

        /// <summary>
        /// 打开Excel文件异常时，添加错误日志信息的标识,当（ErrorCount=1 || ErrorCount / 100 = 0 || ErrorCount < 1000）满足则添加错误消息日志
        /// </summary>
        public int ErrorCount = 0;

        //Csv数据是从何处解析的，1：MES数据表.csv     2:MES数据表二次写入
        public int CsvDataFrom = 1;
       

        public GYSHelperClass HC;
        /// <summary>
        /// Csv实时监听
        /// </summary>
        public void CsvListening()
        {
            Task.Run(() =>
            {
                while (CsvListeningBS)
                {
                    if (transport != null)
                    {
                        if (ExcelHave == false)
                        {
                            FileInfo fi = null;
                            try
                            {
                                fi = new FileInfo(Config.LocalFileUrl);
                            }
                            catch (Exception ex)
                            {
                                AddMcLogs(ex.Message);
                            }
                            if (fi != null)
                            {
                                if (fi.LastWriteTime != dtf)
                                {
                                    if (HC == null)
                                    {
                                        HC = new GYSHelperClass();
                                    }

                                    dtf = fi.LastWriteTime;
                                    try
                                    {
                                        CSV csv = new CSV(Config.LocalFileUrl);
                                        if (csv.RowCount > 1)
                                        {
                                            for (int i = 0; i < csv.Data.Count; i++)
                                            {

                                                if (i < 1)
                                                {
                                                    HC.ClassID = csv.Data[i + 1][6].ToString();
                                                }
                                                else
                                                {
                                                    if (csv.Data[i][2].ToString() != "OK" || csv.Data[i][5].ToString() != "OK")
                                                    {
                                                        HC.DetectStatus = "NG";
                                                    }
                                                    ResultData RD1 = new ResultData();
                                                    ResultData RD2 = new ResultData();
                                                    RD1.CenterFrequency = csv.Data[i][0].ToString();
                                                    RD1.MaxValue = csv.Data[i][1].ToString();
                                                    RD1.FrequencyResult = csv.Data[i][2].ToString();

                                                    RD2.CenterFrequency = csv.Data[i][3].ToString();
                                                    RD2.MaxValue = csv.Data[i][4].ToString();
                                                    RD2.FrequencyResult = csv.Data[i][5].ToString();
                                                    HC.PassageOne.Add(RD1);
                                                    HC.PassageTwo.Add(RD2);
                                                }
                                            }
                                            //Excel表格中有数据的标识改为true
                                            ExcelHave = true;
                                            CsvDataFrom = 1;
                                        }
                                        //将Excel打开时的异常标识清零
                                        ErrorCount = 0;
                                        fi = null;
                                        csv = null;
                                    }
                                    catch (Exception ex)
                                    {
                                        ErrorCount += 1;
                                        if (ErrorCount == 1 || ErrorCount / 100 == 0 || ErrorCount < 1000)
                                        {
                                            AddMcLogs("Excel文件不存在或资源正在使用中，详细信息：" + ex.Message);
                                        }
                                    }
                                }
                                else
                                {
                                    FileInfo fiTwice = null;
                                    try
                                    {
                                        fiTwice = new FileInfo(Config.LocalFileUrlTwice);
                                    }
                                    catch (Exception ex)
                                    {
                                        AddMcLogs(ex.Message);
                                    }
                                    if (fiTwice != null)
                                    {
                                        if (fiTwice.LastWriteTime != dtfTwice)
                                        {
                                            if (HC == null)
                                            {
                                                HC = new GYSHelperClass();
                                            }
                                            dtfTwice = fiTwice.LastWriteTime;
                                            try
                                            {
                                                CSV csv = new CSV(Config.LocalFileUrlTwice);
                                                if (csv.RowCount > 1)
                                                {
                                                    for (int i = 0; i < csv.Data.Count; i++)
                                                    {
                                                        if (i > 0)
                                                        {
                                                            if (csv.Data[i][2].ToString() != "OK" || csv.Data[i][5].ToString() != "OK")
                                                            {
                                                                HC.DetectStatus = "NG";
                                                            }
                                                            if (i < 1)
                                                            {
                                                                HC.ClassID = csv.Data[i][6].ToString();
                                                            }
                                                            else
                                                            {
                                                                ResultData RD1 = new ResultData();
                                                                ResultData RD2 = new ResultData();
                                                                RD1.CenterFrequency = csv.Data[i][0].ToString();
                                                                RD1.MaxValue = csv.Data[i][1].ToString();
                                                                RD1.FrequencyResult = csv.Data[i][2].ToString();

                                                                RD2.CenterFrequency = csv.Data[i][3].ToString();
                                                                RD2.MaxValue = csv.Data[i][4].ToString();
                                                                RD2.FrequencyResult = csv.Data[i][5].ToString();
                                                                HC.PassageOne.Add(RD1);
                                                                HC.PassageTwo.Add(RD2);
                                                            }
                                                        }
                                                    }
                                                    //Excel表格中有数据的标识改为true
                                                    ExcelHave = true;
                                                    CsvDataFrom = 2;
                                                }
                                                //将Excel打开时的异常标识清零
                                                ErrorCount = 0;
                                                fiTwice = null;
                                                csv = null;
                                            }
                                            catch (Exception ex)
                                            {
                                                ErrorCount += 1;
                                                if (ErrorCount == 1 || ErrorCount / 100 == 0 || ErrorCount < 1000)
                                                {
                                                    AddMcLogs("Excel文件不存在或资源正在使用中，详细信息：" + ex.Message);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        Task.Delay(1000).Wait();
                    }
                }
            });
        }
        List<RecordsFile> LPF = new List<RecordsFile>();
        /// <summary>
        /// Csv数据发送到Mes实时监听
        /// </summary>
        private void CsvDataSendListening()
        {
            Task.Run(() =>
            {
                while (TibcoListeningBS)
                {
                    if (transport != null)
                    {
                        if (ExcelHave == true && HC.PassageOne.Count > 0)
                        {
                            StringBuilder SBXMLMessages = new StringBuilder();
                            try
                            {
                                AddMcLogs("正在组合消息字符串");
                                DateTime dtm = DateTime.Now;
                                string TRANSACTIONIDString = dtm.Year.ToString() + dtm.Month.ToString() + dtm.Day.ToString() + dtm.Hour.ToString() + dtm.Minute.ToString() + dtm.Second.ToString() + dtm.Millisecond.ToString() + "GYS";
                                Message message = new Message();
                                message.SendSubject = Config.MesSendSubject;
                                SBXMLMessages.Append($"\r<Message>");
                                SBXMLMessages.Append($"\r\t<Header>");
                                SBXMLMessages.Append($"\r\t\t<MESSAGENAME>NoiseInsepection</MESSAGENAME>");
                                SBXMLMessages.Append($"\r\t\t<SHOPNAME>MODULE</SHOPNAME>");
                                SBXMLMessages.Append($"\r\t\t<MACHINENAME>8MMZS16</MACHINENAME>");
                                SBXMLMessages.Append($"\r\t\t<TRANSACTIONID>" + TRANSACTIONIDString + "</TRANSACTIONID>");
                                SBXMLMessages.Append($"\r\t\t<ORIGINALSOURCESUBJECTNAME>GYS.TO.BOE.MESSAGES</ORIGINALSOURCESUBJECTNAME>");
                                SBXMLMessages.Append($"\r\t\t<SOURCESUBJECTNAME>GYS.TO.BOE.MESSAGES</SOURCESUBJECTNAME>");
                                SBXMLMessages.Append($"\r\t\t<TARGETSUBJECTNAME>" + Config.MesSendSubject + "</TARGETSUBJECTNAME>");
                                SBXMLMessages.Append($"\r\t\t<EVENTUSER>8MMZS16</EVENTUSER>");
                                SBXMLMessages.Append($"\r\t\t<EVENTCOMMENT>NoiseInsepection</EVENTCOMMENT>");
                                SBXMLMessages.Append($"\r\t\t<listener>NoiseInsepection</listener>");
                                SBXMLMessages.Append($"\r\t</Header>");
                                SBXMLMessages.Append($"\r\t<Body>");
                                SBXMLMessages.Append($"\r\t\t<MACHINENAME>8MMZS16</MACHINENAME>");
                                SBXMLMessages.Append($"\r\t\t<UNITNAME>8MMZS16-ST01</UNITNAME>");
                                if (HC.ClassID.Length <= 14)
                                {
                                    SBXMLMessages.Append($"\r\t\t<PRODUCTNAME>" + HC.ClassID + "</PRODUCTNAME>");
                                    SBXMLMessages.Append($"\r\t\t<BLU/>");
                                    SBXMLMessages.Append($"\r\t\t<MODULENAME/>");
                                }
                                else if (HC.ClassID.Length <= 17)
                                {
                                    SBXMLMessages.Append($"\r\t\t<PRODUCTNAME/>");
                                    SBXMLMessages.Append($"\r\t\t<BLU/>");
                                    SBXMLMessages.Append($"\r\t\t<MODULENAME>" + HC.ClassID + "</MODULENAME>");

                                }
                                else
                                {
                                    SBXMLMessages.Append($"\r\t\t<PRODUCTNAME/>");
                                    SBXMLMessages.Append($"\r\t\t<BLU>" + HC.ClassID + "</BLU>");
                                    SBXMLMessages.Append($"\r\t\t<MODULENAME/>");
                                }
                                SBXMLMessages.Append($"\r\t\t<PCB/>");
                                SBXMLMessages.Append($"\r\t\t<FPCA/>");
                                SBXMLMessages.Append($"\r\t\t<CTNO/>");
                                SBXMLMessages.Append($"\r\t\t<RESULT>{HC.DetectStatus}</RESULT>");
                                SBXMLMessages.Append($"\r\t\t<MATERIALLIST>");
                                for (int i = 0; i < 2; i++)
                                {
                                    if (i == 0)
                                    {
                                        SBXMLMessages.Append($"\r\t\t\t<MATERIAL>");
                                        SBXMLMessages.Append($"\r\t\t\t\t<CHANNEL>Channel{i + 1}</CHANNEL>");
                                        for (int j = 0; j < HC.PassageOne.Count; j++)
                                        {
                                            SBXMLMessages.Append($"\r\t\t\t\t<RESULT{j + 1}>" + HC.PassageOne[j].FrequencyResult + "</RESULT" + (j + 1) + ">");
                                            SBXMLMessages.Append($"\r\t\t\t\t<FREQUENCY{j + 1}>" + HC.PassageOne[j].CenterFrequency + "</FREQUENCY" + (j + 1) + ">");
                                            SBXMLMessages.Append($"\r\t\t\t\t<VALUE{j + 1}>" + HC.PassageOne[j].MaxValue + "</VALUE" + (j + 1) + ">");
                                        }
                                        SBXMLMessages.Append($"\r\t\t\t</MATERIAL>");
                                    }
                                    else
                                    {
                                        SBXMLMessages.Append($"\r\t\t\t<MATERIAL>");
                                        SBXMLMessages.Append($"\r\t\t\t\t<CHANNEL>Channel{i + 1}</CHANNEL>");
                                        for (int j = 0; j < HC.PassageTwo.Count; j++)
                                        {
                                            SBXMLMessages.Append($"\r\t\t\t\t<RESULT{j + 1}>" + HC.PassageTwo[j].FrequencyResult + "</RESULT" + (j + 1) + ">");
                                            SBXMLMessages.Append($"\r\t\t\t\t<FREQUENCY{j + 1}>" + HC.PassageTwo[j].CenterFrequency + "</FREQUENCY" + (j + 1) + ">");
                                            SBXMLMessages.Append($"\r\t\t\t\t<VALUE{j + 1}>" + HC.PassageTwo[j].MaxValue + "</VALUE" + (j + 1) + ">");
                                        }
                                        SBXMLMessages.Append($"\r\t\t\t</MATERIAL>");
                                    }

                                }
                                SBXMLMessages.Append($"\r\t\t</MATERIALLIST>");
                                SBXMLMessages.Append($"\r\t</Body>");
                                SBXMLMessages.Append($"\r\t<Return>");
                                SBXMLMessages.Append($"\r\t\t<RETURNCODE>0</RETURNCODE>");
                                SBXMLMessages.Append($"\r\t\t<RETURNMESSAGE/>");
                                SBXMLMessages.Append($"\r\t</Return>");
                                SBXMLMessages.Append($"\r</Message>");
                                AddMcLogs("消息字符串组合成功");

                                message.AddField("Message", SBXMLMessages.ToString());
                                transport.Send(message);
                                //Send日志写入文件
                                CreateSendMessageLogs($"\r[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [MES Log] [info] Message :Send OK! !\r {SBXMLMessages.ToString()} \r");
                                AddMcLogs($"Tibco消息发送成功\r[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [MES Log] [info] Message :Send OK! !\r {SBXMLMessages.ToString()} \r");

                                SBXMLMessages.Clear();
                                HC = null;
                            }
                            catch (RendezvousException exception)
                            {
                                //Excel中有数据的标识改为false
                                ExcelHave = false;
                                ttx = "Tibco服务断开连接";
                                ttxcl = Brushes.Red;
                                TIBCO.Rendezvous.Environment.Close();
                                transport = null;
                                AddMcLogs($"Tibco消息发送失败\r[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [MES Log] [info] Message :Send Failed! !\r {SBXMLMessages.ToString()} \r");
                                SBXMLMessages.Clear();
                                //添加消息日志记录
                                AddMcLogs("Error sending a message:" + exception.StackTrace);

                            }

                        }

                        //Excel中有数据的标识改为false
                        ExcelHave = false;

                    }

                    //Excel中有数据的标识改为false
                    ExcelHave = false;
                    Task.Delay(500).Wait();
                }
            });
        }

        
        public void UpdateTb(TextBlock tb, string text,SolidColorBrush scb)
        {
            tb.Text = text;
            tb.Foreground = scb;
        }
        public void upui(TextBlock tb,string tx,SolidColorBrush scb)
        {
            Action<TextBlock, String, SolidColorBrush> updateAction = new Action<TextBlock, string, SolidColorBrush>(UpdateTb);
            tb.Dispatcher.BeginInvoke(updateAction, tb, tx,scb);
        }
        
        /// <summary>
        /// Tibco协议初始化
        /// </summary>
        public void TibcoInit()
        {
            try
            {
               
                upui(Ticst, "正在打开Ticbo环境", Brushes.Orange);
                TIBCO.Rendezvous.Environment.Open();
                TIBCO.Rendezvous.Environment.StringEncoding = System.Text.Encoding.GetEncoding("UTF-8");
                
                upui(Ticst, "Tibco协议环境已打开", Brushes.Orange);
                AddMcLogs("Tibco协议环境已打开");
                AddMcLogs("正在进行Tibco服务器连接");

                upui(Ticst, "正在进行Tibco服务器连接", Brushes.Orange);
                for (int i = 0; i < DeamonList.Count; i++)
                {
                    try
                    {
                        //transport = new NetTransport(hdc[0].ToString(), hdc[1].ToString(), hdc[2].ToString());
                        transport = new NetTransport(Config.MesCommunicationsConfiguration.Service, Config.MesCommunicationsConfiguration.NetWork, DeamonList[i].ToString());

                        upui(Ticst, "连接成功", Brushes.Green);
                        AddMcLogs("Tibco服务器连接成功");
                        break;
                    }
                    catch (Exception ex)
                    {
                        upui(Ticst, "连接失败", Brushes.Red);
                        AddMcLogs("创建连接失败，Daemon:" + DeamonList[i].ToString() + "。详细错误信息：" + ex.Message);
                        Thread.Sleep(1000);
                        upui(Ticst, "重连中...", Brushes.Red);
                    }
                }
            }
            catch (RendezvousException exception)
            {
                AddMcLogs("Failed to open Rendezvous Environment:" + exception.StackTrace);
            }
            //string zfc = File.ReadAllText(str + "/MyTest.txt", Encoding.UTF8);
            //string[] hdc = zfc.Split(',');
            
        }

        /// <summary>
        /// 添加界面消息日志
        /// </summary>
        /// <param name="msg"></param>
        private void AddMcLogs(string msg)
        {
            App.Current.Dispatcher.Invoke(() =>
            {
                //添加界面日志显示
                Logs.Insert(0, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} \r {msg}");
                if (Logs.Count > 100)
                {
                    Logs.Clear();
                }
                //日志写入文件
                CreateLogsFile($"\r{DateTime.Now:yyyy-MM-dd HH:mm:ss}-日志开始 \r {msg} \r{DateTime.Now:yyyy-MM-dd HH:mm:ss}-日志结束 \r");
            });
        }
        /// <summary>
        /// Tibco初始化按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (transport == null)
            {
                AddMcLogs("Ticbo服务正在重连中...");
                Ticst.Text = "Ticbo服务正在重连中...";
                Ticst.Foreground = Brushes.Orange;
                //Tibco协议初始化
                Thread thread = new Thread(new ThreadStart(TibcoInit));
                thread.Start();
            }
            else
            {
                MessageBox.Show("Tibco服务已连接，无需重连!");
            }
        }
        /// <summary>
        /// 将系统消息写入日志文件
        /// </summary>
        public void CreateLogsFile(string Content)
        {
            DateTime dtn = DateTime.Now;
            string txtFileName = dtn.Year.ToString() + dtn.Month.ToString() + dtn.Day.ToString();
            if (!Directory.Exists(str + "/SystemLogs"))
            {
                System.IO.Directory.CreateDirectory(str + "/SystemLogs");
            }
            System.IO.File.AppendAllText(str + "/SystemLogs/" + txtFileName + ".txt", Content);
        }
        /// <summary>
        /// 将发送给Mes的消息写入日志文件
        /// </summary>
        public void CreateSendMessageLogs(string Content)
        {
            DateTime dtn = DateTime.Now;
            string txtFileName = dtn.Year.ToString() + dtn.Month.ToString() + dtn.Day.ToString() + "_Tibco发送消息日志";
            if (!Directory.Exists(str + "/SendMesLogs"))
            {
                System.IO.Directory.CreateDirectory(str + "/SendMesLogs");
            }
            System.IO.File.AppendAllText(str + "/SendMesLogs/" + txtFileName + ".txt", Content);
        }
        

    }
}
